package ae.pcfc.etks.online.wf.service.client.provider;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.client.core.WebServiceMessageCallback;
import org.springframework.ws.client.core.WebServiceTemplate;
import org.springframework.ws.soap.SoapMessage;

import ae.pcfc.etks.online.common.exception.WFException;
import ae.pcfc.etks.online.wf.ConstantsWF;
import ae.pcfc.etks.online.wf.Utils;
import ae.pcfc.etks.online.wf.WFProcessType;
import ae.pcfc.etks.online.wf.service.client.BaseWF;
import ae.pcfc.etks.online.wf.service.client.vo.ActiveTaskVO;
import ae.pcfc.etks.online.wf.service.client.vo.CompleteStepVO;
import ae.pcfc.etks.online.wf.service.client.vo.LaunchIncidentVO;
import ae.pcfc.etks.online.wf.service.client.vo.TaskInformationVO;
import ae.pcfc.etks.online.wf.service.client.vo.WFBaseVO;
import ae.pcfc.etks.online.wf.service.types.AbortIncident;
import ae.pcfc.etks.online.wf.service.types.AbortIncidentResponse;
import ae.pcfc.etks.online.wf.service.types.ArrayOfVariable;
import ae.pcfc.etks.online.wf.service.types.CTaskInfo;
import ae.pcfc.etks.online.wf.service.types.CompleteStep;
import ae.pcfc.etks.online.wf.service.types.CompleteStepResponse;
import ae.pcfc.etks.online.wf.service.types.GetActiveTasks;
import ae.pcfc.etks.online.wf.service.types.GetActiveTasksResponse;
import ae.pcfc.etks.online.wf.service.types.GetTaskInformation;
import ae.pcfc.etks.online.wf.service.types.GetTaskInformationResponse;
import ae.pcfc.etks.online.wf.service.types.LaunchIncident;
import ae.pcfc.etks.online.wf.service.types.LaunchIncidentResponse;
import ae.pcfc.etks.online.wf.service.types.ObjectFactory;

public abstract class BaseWFImpl implements BaseWF {

    protected WebServiceTemplate wsTemplate;
    protected Map<String, String> webServicesEndPointsMap;
    protected String formsAppURL;
    protected WFProcessType wfProcessType;

    public WFProcessType getWfProcessType() {
        return wfProcessType;
    }

    /**
     * @param webServicesEndPointsMap
     *            the webServicesEndPointsMap to set
     */
    @Resource(name = "ultWFWebServicesEndPointsMap")
    public void setWebServicesEndPointsMap(Map webServicesEndPointsMap) {
	this.webServicesEndPointsMap = webServicesEndPointsMap;
    }

    /**
     * @param formsAppURL
     *            the formsAppURL to set
     */
    @Resource(name = "formsAppURL")
    public void setFormsAppURL(String formsAppURL) {
	this.formsAppURL = formsAppURL;
    }

    /**
     * @param wsTemplate
     *            the wsTemplate to set
     */
    @Resource(name = "ultWFWsTemplate")
    public void setWsTemplate(WebServiceTemplate wsTemplate) {
	this.wsTemplate = wsTemplate;
    }

    public <T extends LaunchIncidentVO> Integer launchIncident(T incidentVO) {
	String classKey = StringUtils.delete(
		ClassUtils.getShortName(this.getClass()), "Impl");
	String classURIValue = webServicesEndPointsMap.get(classKey);

	Map<String, Object> paramsMap = new HashMap<String, Object>();

	if (!StringUtils.hasText(incidentVO.getgFormsAppURL())) {
	    incidentVO.setgFormsAppURL(formsAppURL);
	}
	
	ObjectFactory factory = new ObjectFactory();
	LaunchIncident incident = factory.createLaunchIncident();
	incident.setStrUserName(incidentVO.getStrUserName());
	incident.setStrSummary(incidentVO.getStrSummary());
	//incident.setStrUserName("Annonymous");
	//incident.setNIncidentNo(-1);

	ArrayOfVariable arrVar = Utils.convertToWFVariable(incidentVO);
	incident.setVarList(arrVar);

	LaunchIncidentResponse response = (LaunchIncidentResponse) wsTemplate
		.marshalSendAndReceive(classURIValue, incident,
			new WebServiceMessageCallback() {

			    public void doWithMessage(WebServiceMessage message) {
				((SoapMessage) message)
					.setSoapAction(ConstantsWF.LAUNCH_INCIDENT_SOAP_ACTION);
			    }
			});
	/*LaunchIncidentResponse response = (LaunchIncidentResponse) wsTemplate
	.marshalSendAndReceive(classURIValue, incident);*/
	if (response.getNIncidentNo() <= 0) {
	    throw new WFException(response.getStrError());
	}
	return response.getNIncidentNo();

    }

    public <T extends WFBaseVO> List<ActiveTaskVO> getActiveTasks(T wfBaseVO) {
	String classKey = StringUtils.delete(
		ClassUtils.getShortName(this.getClass()), "Impl");
	String classURIValue = webServicesEndPointsMap.get(classKey);

	Map<String, Object> paramsMap = new HashMap<String, Object>();

	GetActiveTasks processTasks = new GetActiveTasks();
	processTasks.setStrUserName(wfBaseVO.getStrUserName());
	

	GetActiveTasksResponse response = (GetActiveTasksResponse) wsTemplate
		.marshalSendAndReceive(classURIValue, processTasks,
			new WebServiceMessageCallback() {

			    public void doWithMessage(WebServiceMessage message) {
				((SoapMessage) message)
					.setSoapAction(ConstantsWF.GET_ACTIVE_TASKS_SOAP_ACTION);
			    }
			});
	if (response.getTaskList() == null
		|| response.getTaskList().getCTaskInfo().size() == 0) {
	    return null;
	}

	List<ActiveTaskVO> returnList = new ArrayList<ActiveTaskVO>();
	for (CTaskInfo taskInfo : response.getTaskList().getCTaskInfo()) {
	    ActiveTaskVO taskVO = new ActiveTaskVO();
	    taskVO.setnIncidentNumber(taskInfo.getMNIncidentNum());
	    taskVO.setStrStepName(taskInfo.getMStrStepLabel());
	    taskVO.setStrSummary(taskInfo.getMStrSummary());
	    taskVO.setStrProcessCode(this.getWfProcessType().getProcessCode());
	    returnList.add(taskVO);
	}
	return returnList;

    }

    public <T extends CompleteStepVO> void completeStep(T stepVO) {
	String classKey = StringUtils.delete(
		ClassUtils.getShortName(this.getClass()), "Impl");
	String classURIValue = webServicesEndPointsMap.get(classKey);

	Map<String, Object> paramsMap = new HashMap<String, Object>();

	CompleteStep step = new CompleteStep();
	step.setStrUserName(stepVO.getStrUserName());
	step.setNIncidentNumber(stepVO.getnIncidentNumber());
	step.setStrStepName(stepVO.getStrStepName());
	step.setStrSummary(stepVO.getStrSummary());
	step.setStrMemo(stepVO.getStrMemo());

	ArrayOfVariable arrVar = Utils.convertToWFVariable(stepVO);
	step.setVarList(arrVar);
	/*
	 * for(Variable var : arrVar.getVariable()) {
	 * System.out.println(var.getStrVariableName()); for(Object varValue :
	 * var.getObjVariableValue().getAnyType()) {
	 * System.out.println(varValue); }
	 * 
	 * }
	 */

	CompleteStepResponse response = (CompleteStepResponse) wsTemplate
		.marshalSendAndReceive(classURIValue, step,
			new WebServiceMessageCallback() {

			    public void doWithMessage(WebServiceMessage message) {
				((SoapMessage) message)
					.setSoapAction(ConstantsWF.COMPLETE_STEP_SOAP_ACTION);
			    }
			});
	if (!response.isCompleteStepResult()) {
	    throw new WFException(response.getStrError());
	}

    }
    public <T extends CompleteStepVO> void abortIncident(T stepVO){
	String classKey = StringUtils.delete(
		ClassUtils.getShortName(this.getClass()), "Impl");
	String classURIValue = webServicesEndPointsMap.get(classKey);


	AbortIncident abortIncident = new AbortIncident();
	abortIncident.setStrUserName(stepVO.getStrUserName());
	abortIncident.setNIncidentNumber(stepVO.getnIncidentNumber());
	abortIncident.setStrSummary(stepVO.getStrSummary());

	/*ArrayOfVariable arrVar = Utils.convertToWFVariable(stepVO);
	step.setVarList(arrVar);*/
	/*
	 * for(Variable var : arrVar.getVariable()) {
	 * System.out.println(var.getStrVariableName()); for(Object varValue :
	 * var.getObjVariableValue().getAnyType()) {
	 * System.out.println(varValue); }
	 * 
	 * }
	 */

	AbortIncidentResponse response = (AbortIncidentResponse) wsTemplate
		.marshalSendAndReceive(classURIValue, abortIncident,
			new WebServiceMessageCallback() {

			    public void doWithMessage(WebServiceMessage message) {
				((SoapMessage) message)
					.setSoapAction(ConstantsWF.ABORT_INCIDENT_SOAP_ACTION);
			    }
			});
	if (!response.isAbortIncidentResult()) {
	    throw new WFException(response.getStrError());
	}
    }
    
    public TaskInformationVO getTaskInformation(String userName, Integer incedentNo)
    {
		String classKey = StringUtils.delete(
			ClassUtils.getShortName(this.getClass()), "Impl");
		String classURIValue = webServicesEndPointsMap.get(classKey);

		
		ObjectFactory factory = new ObjectFactory();
		//Task
		GetTaskInformation getTaskInformation = factory.createGetTaskInformation();
		getTaskInformation.setStrUserName(userName);
		getTaskInformation.setNIncidentNumber(incedentNo);
		
		GetTaskInformationResponse response = (GetTaskInformationResponse) wsTemplate
    			.marshalSendAndReceive(classURIValue, getTaskInformation,
        				new WebServiceMessageCallback() {

        				    public void doWithMessage(WebServiceMessage message) {
        					((SoapMessage) message)
        						.setSoapAction(ConstantsWF.GET_TASK_INFORMATION_SOAP_ACTION);
        				    }
        				});
    	
		//if(response.getStrError() != null && !response.getStrError().equals(""))
		{
			TaskInformationVO taskInformationVO = new TaskInformationVO();
			
			if(response.getVarList() != null && response.getVarList().getVariable() != null && response.getVarList().getVariable().size() > 0)
			{
				for(int i = 0; i < response.getVarList().getVariable().size(); i++)
				{
					if(response.getVarList().getVariable().get(i).getStrVariableName().equals("gApprovalCED"))
					{
						taskInformationVO.setgApprovalCED(response.getVarList().getVariable().get(i).getObjVariableValue().getAnyType().get(0).toString());
					}
					else if(response.getVarList().getVariable().get(i).getStrVariableName().equals("gApprovalCLD"))
					{
						taskInformationVO.setgApprovalCLD(response.getVarList().getVariable().get(i).getObjVariableValue().getAnyType().get(0).toString());
					}
					else if(response.getVarList().getVariable().get(i).getStrVariableName().equals("gApprovalEHS"))
					{
						taskInformationVO.setgApprovalEHS(response.getVarList().getVariable().get(i).getObjVariableValue().getAnyType().get(0).toString());
					}
					else if(response.getVarList().getVariable().get(i).getStrVariableName().equals("gApprovalFIN"))
					{
						taskInformationVO.setgApprovalFIN(response.getVarList().getVariable().get(i).getObjVariableValue().getAnyType().get(0).toString());
					}
					else if(response.getVarList().getVariable().get(i).getStrVariableName().equals("lStepCode"))
					{
						taskInformationVO.setlStepCode(response.getVarList().getVariable().get(i).getObjVariableValue().getAnyType().get(0).toString());
						taskInformationVO.setlStepCode(taskInformationVO.getlStepCode().replaceFirst("REV", ""));
					}
					
					
				}
				
				return taskInformationVO;
			}			
		}
    		
    	return null;
    }    
}
